package cn.yoaket.web;

import cn.yoaket.algorithm.Dijkstra;
import cn.yoaket.algorithm.Shadow;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import cn.yoaket.unit.Edge;
import cn.yoaket.unit.Point;
import org.locationtech.jts.geom.Polygon;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

@WebServlet("/PathGenerate")
public class PathGenerate extends HttpServlet {

    String toCoordinates(Edge path){
        StringBuilder str = new StringBuilder();
        str.append("[");
        for (Point vertex : path.vertexes()) {
            str.append("[").append(vertex.getX()).append(",").append(vertex.getY()).append("]").append(",");
        }
        str.deleteCharAt(str.length()-1);
        str.append("]");
        return str.toString();
    }


    Edge shortPath(Point begin,Point end,List<Edge> roads){
        for (Edge road : roads) {
            road.setRatio(0);
        }
        return Dijkstra.execute(begin, end, roads);
    }

    Edge coolPath(Point begin,Point end,double azAngle,double elAngle,List<Edge> roads,List<Polygon> buildings){
        List<Polygon> shadows = new ArrayList<>();
        for (Polygon building : buildings) {
            shadows.add(Shadow.projection(building, azAngle, elAngle));
        }
        for (Edge road : roads) {
            Shadow.getRatio(road,shadows);
        }
        return Dijkstra.execute(begin, end, roads);
    }


    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String[] start = request.getParameter("start").split(",");
        String[] goal = request.getParameter("goal").split(",");
        String el = request.getParameter("el");
        String az = request.getParameter("az");

        Point begin = new Point(Double.parseDouble(start[0]),Double.parseDouble(start[1]));
        Point end = new Point(Double.parseDouble(goal[0]),Double.parseDouble(goal[1]));

        ServletContext context = getServletContext();
        List<Edge> roads = (List<Edge>)context.getAttribute("edges");
        List<Polygon> buildings = (List<Polygon>)context.getAttribute("buildings");

        Edge shortPath = shortPath(begin,end,roads);
        Edge coolPath;

        //天黑时最短路径就是最优路径
        if(az.equals("dark") && el.equals("dark")){
            coolPath = shortPath;
        }else{
            double azAngle = Double.parseDouble(az);
            double elAngle = Double.parseDouble(el)-180;
            coolPath = coolPath(begin,end,azAngle,elAngle,roads,buildings);
        }

        response.setContentType("text/json");
        PrintWriter out = response.getWriter();
        out.print("["+toCoordinates(shortPath)+","+toCoordinates(coolPath)+"]");


    }
}
